<template>
	<view class="page-session" :style="{
			height,
		}" @touchmove="onTouchMove">
		<view class="header">
			<cl-topbar background-color="transparent" :border="false" color="#ffffff">
				<view class="cl-topbar__text" @tap="toDetail">
					<text class="cl-topbar__title">渣渣唱歌房</text>
				</view>
			</cl-topbar>
		</view>

		<!-- 房间用户 -->
		<chat-user></chat-user>

		<!-- 消息列表 -->
		<view class="message-list" @tap="onRetract">
			<scroll-view class="scroller" scroll-y scroll-with-animation :scroll-top="scroller.top"
				:scroll-into-view="scroller.intoView" :upper-threshold="20">
				<!-- 加载更多 -->
				<view class="loadmore" v-if="loading">
					<cl-loadmore text="" finish-text="" loading :divider="false"></cl-loadmore>
				</view>

				<!-- 内容块 -->
				<chat-message ref="message" :list="list"></chat-message>
			</scroll-view>

			<!-- 录音弹窗 -->
			<cl-popup :visible.sync="voice.visible" direction="center" padding="0" border-radius="10rpx">
				<view class="popup-voice" :class="[
						{
							'is-cancel': voiceIsCancel,
						},
					]">
					<text class="popup-voice__time">{{ voice.duration | voice_duration }}</text>
					<text class="popup-voice__desc">松开发送，上滑取消</text>
				</view>
			</cl-popup>
		</view>

		<!-- 操作栏 -->
		<view class="opbar">
			<view class="main">
				<!-- 麦克风 -->
				<!-- #ifndef H5 -->
				<view class="icon">
					<text class="chat-iconfont icon-microphone" v-if="!op.isMicrophone" @tap="showMicrophone"></text>
					<text class="chat-iconfont icon-keyboard" @tap="hideMicrophone" v-else></text>
				</view>
				<!-- #endif -->

				<!-- 输入框 -->
				<view class="input">
					<button v-if="op.isMicrophone" class="press-btn" @longpress="onLongPress" @touchend="onRelease">
						{{ voice.visible ? "松开结束" : "按住说话" }}
					</button>
					<cl-input v-else v-model="value" confirm-type="send" confirm-hold round fill placeholder="说点什么吧"
						:cursor-spacing="10" :adjust-position="false" @focus="onFocus" @blur="onBlur"
						@confirm="onTextSend" @keyboardheightchange="onKeyBoardHeightChange">
						<view class="send" slot="append">
							<cl-button round @tap="onTextSend">发送</cl-button>
						</view>
					</cl-input>
				</view>
			</view>
		</view>

		<!-- 视频弹窗 -->
		<cl-popup :visible.sync="video.visible" direction="center" force-update padding="0" border-radius="10rpx"
			@close="onVideoClose">
			<video id="video" autoplay :src="video.url" style="display: block"></video>
		</cl-popup>

		<!-- 背景图 -->
		<view class="chat-bgc">
			<image src="@/static/images/chat-bgc.png" mode="scaleToFill" />
		</view>

		<ArticleShare :show="shareshow" @changeShare="share()"></ArticleShare>
	</view>
</template>

<script>
	import {
		debounce
	} from "cl-uni/utils";
	import ChatMessage from "./components/message";
	import ChatUser from "./components/user";
	import ArticleShare from "@/components/article-share.vue";

	// 录音设备
	const recorderManager = uni.getRecorderManager();

	// 平台
	const {
		platform
	} = uni.getSystemInfoSync();

	export default {
		components: {
			ChatMessage,
			ChatUser,
			ArticleShare
		},

		data() {
			return {
				shareshow: false,
				// 平台
				platform,
				// 输入框文本
				value: "",
				// 键盘高度
				keyBoardHeight: 0,
				// 聊天记录数据
				list: [{
						contentType: 0,
						fromId: 1,
						content: {
							text: "Hello",
						},
					},
					{
						contentType: 0,
						fromId: 2,
						name: "每天都很棒",
						avatarUrl: require("@/static/images/meet-1.png"),
						content: {
							text: "我进来陪你聊天了"
						},
					},
					{
						contentType: 0,
						fromId: 2,
						name: "神仙都没用",
						avatarUrl: require("@/static/images/meet-1.png"),
						content: {
							text: "文本文本",
						},
					},
				],
				// 底部操作栏配置
				op: {
					isMicrophone: false,
					isEmoji: false,
					isTools: false,
				},
				// 滚动条配置
				scroller: {
					top: 0,
					intoView: "",
				},
				// 视频配置
				video: {
					visible: false,
				},
				// 音频配置
				voice: {
					visible: false,
					duration: 0,
					timer: null,
					down: 0,
					move: 0,
				},
				// 加载进度
				loading: false,
			};
		},

		computed: {
			// 计算屏幕高度
			height() {
				return this.keyBoardHeight > 0 ?
					`calc(100% - ${this.keyBoardHeight}px + env(safe-area-inset-bottom))` :
					"100%";
			},

			// 录音滑动是否取消
			voiceIsCancel() {
				return this.voice.move ? this.voice.down - this.voice.move > 50 : false;
			},
		},

		filters: {
			voice_duration(t) {
				return `00:${t < 10 ? `0${t}` : t}`;
			},
		},
		onLoad() {
			const vm = this;
			uni.$on('updateShareShow', function(data) {
				console.log("ccvvvv");
				vm.shareshow = !vm.shareshow;
			})
		},

		methods: {
			// 监听键盘高度
			onKeyBoardHeightChange(e) {
				this.keyBoardHeight = e.detail.height;
			},
			share() {
				this.shareshow = !this.shareshow;
			},
			// 滑动监听
			onTouchMove(e) {
				if (this.voice.visible) {
					// 记录移动的位置
					this.voice.move = e.changedTouches[0].clientY;
				}
			},

			// 长按说话
			onLongPress(e) {
				// 关闭已存在播放声音
				this.$refs["message"].voicePause();

				this.$nextTick(() => {
					// 记录按下位置
					this.voice.down = e.detail.y;
					// 清空移动位置
					this.voice.move = 0;
					// 显示弹窗
					this.voice.visible = true;
					// 开始录音
					recorderManager.start({
						duration: 60000,
						format: "mp3",
						frameSize: 50,
					});
					// 计数器
					this.voice.timer = setInterval(() => {
						if (this.voice.duration >= 60) {
							this.onRelease(e);
						} else {
							this.voice.duration += 1;
						}
					}, 1000);
				});
			},

			// 松开
			onRelease(e) {
				// 记录移动位置
				this.voice.move = e.changedTouches[0].clientY;

				// 暂停事件
				recorderManager.onStop(async (res) => {
					// 判断是否取消
					if (!this.voiceIsCancel) {}
				});
				// 清除计时器
				clearInterval(this.voice.timer);
				// 暂停录音
				recorderManager.stop();
				// 关闭弹窗
				this.voice.visible = false;
				// 清空时常
				this.voice.duration = 0;
			},

			// 显示麦克风
			showMicrophone() {
				this.op.isMicrophone = true;
				this.hideTools();
				this.hideEmoji();
				this.hideKeyBoard();
			},

			// 隐藏麦克风
			hideMicrophone() {
				this.op.isMicrophone = false;
			},

			// 显示表情
			showEmoji() {
				this.op.isEmoji = true;
				this.hideTools();
				this.hideMicrophone();
				this.scrollToBottom();
			},

			// 隐藏表情
			hideEmoji() {
				this.op.isEmoji = false;
			},

			// 显示工具栏
			showTools() {
				this.op.isTools = true;
				this.hideEmoji();
				this.hideMicrophone();
				this.scrollToBottom();
			},

			// 隐藏工具栏
			hideTools() {
				this.op.isTools = false;
			},

			// 隐藏键盘
			hideKeyBoard() {
				this.keyBoardHeight = 0;
			},

			// 滑动到底部
			scrollToBottom: debounce(function() {
				this.$nextTick(() => {
					this.scroller.top = 1000000 + parseInt(Math.random() * 100);
				});
			}, 300),

			// 收起
			onRetract() {
				this.hideTools();
				this.hideEmoji();
			},

			// 聚焦
			onFocus() {
				this.hideEmoji();
				this.hideTools();
				this.scrollToBottom();
			},

			// 失焦
			onBlur() {
				this.hideKeyBoard();
			},

			// 发送消息
			onTextSend() {
				if (this.value) {
					this.sendMessage({
							contentType: 0,
							content: {
								text: this.value,
							},
						},
						true
					);

					this.value = "";
				}
			},

			// 表情选择
			onEmojiSelect(url) {
				this.sendMessage({
						contentType: 2,
						content: {
							imageUrl: url,
						},
					},
					true
				);
			},

			// 发送语音
			onVoiceSend({
				url,
				duration
			}) {
				this.sendMessage({
						contentType: 3,
						content: {
							voiceUrl: url,
							duration,
						},
					},
					true
				);
			},

			// 发送消息
			sendMessage(data, isAppend) {
				// socket.send

				data.fromId = 1;

				if (isAppend) {
					this.append(data);
				}
			},

			// 追加数据到开头
			prepend(...data) {
				this.list.unshift(...data.filter(Boolean).reverse());
			},

			// 追加数据到结尾
			append(...data) {
				this.list.push(
					...data
					.map((e) => {
						e.animation = true;
						return e;
					})
					.filter(Boolean)
				);
				this.scrollToBottom();
			},

			// 关闭视频弹窗
			onVideoClose() {
				const video = uni.createVideoContext("video");
				video.pause();
			},

			// 聊天详情
			toDetail() {
				uni.navigateTo({
					url: "/pages/chat/detail",
				});
			},
		},
	};
</script>

<style lang="scss">
	@import "./static/css/iconfont.scss";

	page {
		height: 100%;
		overflow: hidden;
	}
</style>

<style lang="scss" scoped>
	.page-session {
		display: flex;
		flex-direction: column;
		padding-bottom: env(safe-area-inset-bottom);
		box-sizing: border-box;
		height: 100%;

		.message-list {
			flex: 1;
			overflow: hidden;
			position: relative;

			.loadmore {
				margin: 10rpx 0;
			}

			.scroller {
				height: 100%;
			}

			/deep/.cl-popup {
				&__wrapper {
					position: absolute;
				}
			}
		}

		.opbar {
			flex-shrink: 0;
			z-index: 9;
			background-color: transparent;

			.main {
				display: flex;
				align-items: center;
				height: 100rpx;

				.icon {
					height: 80rpx;
					width: 80rpx;
					line-height: 80rpx;
					text-align: center;
					flex-shrink: 0;

					.chat-iconfont {
						font-size: 60rpx;
					}
				}

				.input {
					flex: 1;
					margin: 0 10rpx;
					height: 70rpx;
					line-height: 70rpx;

					.press-btn {
						display: inline-block;
						height: 70rpx;
						width: 100%;
						line-height: 70rpx;
						color: #666;
						border: 1rpx solid #dcdfe6;
						font-size: 24rpx;
						background-color: #fff;
						margin: 0;
						border-radius: 70rpx;
						box-sizing: border-box;

						&::after {
							border: 0;
						}

						&:active {
							background-color: #f7f7f7;
						}
					}

					.cl-input {
						background: rgba(0, 0, 0, 0.3);
						border: 0;
					}

					.uni-input-placeholder {
						font-size: 28rpx;
						font-weight: 400;
						color: #cccccc;
					}

					.send {
						display: flex;
						align-items: center;
						position: relative;
						height: 100%;
						z-index: 99;

						/deep/.cl-button {
							width: 108rpx;
							height: 54rpx;
							background: linear-gradient(92deg, #ff829c 0%, #ff5a70 100%);

							&__text {
								font-size: 28rpx;
								font-weight: 400;
								color: #ffffff;
							}
						}
					}
				}
			}
		}

		.popup-voice {
			display: flex;
			flex-direction: column;
			align-items: center;
			padding: 20rpx;

			&.is-cancel {
				background-color: red;
				color: #fff;
			}

			&__time {
				font-size: 28rpx;
				margin-bottom: 20rpx;
				letter-spacing: 1rpx;
			}

			&__desc {
				font-size: 24rpx;
			}
		}

		.chat-bgc {
			position: fixed;
			top: 0;
			left: 0;
			width: 100%;
			height: 100%;
			z-index: -1;

			image {
				width: 100%;
				height: 100%;
			}
		}
	}
</style>